home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / hsclib / size.c < prev    next >
C/C++ Source or Header  |  1996-11-15  |  13KB  |  394 lines

  1. /*
  2.  * hsclib/size.c
  3.  *
  4.  * evaluate values for WIDTH and HEIGHT from file
  5.  *
  6.  * Copyright (C) 1996  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated:  8-Nov-1996
  23.  * created:  7-Jan-1996
  24.  */
  25.  
  26. #include "hsclib/inc_base.h"
  27.  
  28. #include "hsclib/uri.h"
  29.  
  30. /* markers for JFIF/JPEG that contain
  31.  * information about image dimension
  32.  */
  33. static UBYTE msof[] =
  34. {
  35.     /* M_SOF0  */ 0xc0,
  36.     /* M_SOF1  */ 0xc1,
  37.     /* M_SOF2  */ 0xc2,
  38.     /* M_SOF3  */ 0xc3,
  39.     /* M_SOF5  */ 0xc5,
  40.     /* M_SOF6  */ 0xc6,
  41.     /* M_SOF7  */ 0xc7,
  42.     /* M_SOF9  */ 0xc9,
  43.     /* M_SOF10 */ 0xca,
  44.     /* M_SOF11 */ 0xcb,
  45.     /* M_SOF13 */ 0xcd,
  46.     /* M_SOF14 */ 0xce,
  47.     /* M_SOF15 */ 0xcf,
  48.     /* end     */ 0x00};
  49.  
  50. /*
  51.  *
  52.  * global funs
  53.  *
  54.  */
  55.  
  56. /*
  57.  * try_set_attr
  58.  *
  59.  * if attribute exists and it's value is empty, set
  60.  * new value and update tag-attribute-string
  61.  */
  62. static VOID try_setattr(HSCPRC * hp, HSCVAR * attr, ULONG value)
  63. {
  64.     if (attr)
  65.     {
  66.         STRPTR old_value = get_vartext(attr);
  67.         STRPTR new_value = long2str(value);
  68.         if (!old_value)
  69.         {
  70.             /* set new value */
  71.             set_vartext(attr, new_value);
  72.  
  73.             /* append attribute name and "=" */
  74.             app_estr(hp->tag_attr_str, " ");
  75.             app_estr(hp->tag_attr_str, attr->name);
  76.             app_estr(hp->tag_attr_str, "=");
  77.  
  78.             /* append quotes and value */
  79.             if ((hp->quotemode == QMODE_KEEP) || (hp->quotemode == QMODE_DOUBLE))
  80.                 app_estrch(hp->tag_attr_str, '\"');
  81.             else if (hp->quotemode == QMODE_SINGLE)
  82.                 app_estrch(hp->tag_attr_str, '\'');
  83.             app_estr(hp->tag_attr_str, long2str(value));        /* append value */
  84.             if ((hp->quotemode == QMODE_KEEP) || (hp->quotemode == QMODE_DOUBLE))
  85.                 app_estrch(hp->tag_attr_str, '\"');
  86.             else if (hp->quotemode == QMODE_SINGLE)
  87.                 app_estrch(hp->tag_attr_str, '\'');
  88.  
  89.         }
  90.         else
  91.         {
  92.             /* validate old value */
  93.             if (strcmp(old_value, new_value))
  94.             {
  95.                 hsc_message(hp, MSG_UNEX_ATTR_VALUE,
  96.                             "unexpected value for %A: expected %q, found %q",
  97.                             attr, new_value, old_value);
  98.             }
  99.         }
  100.     }
  101. }
  102.  
  103. /*
  104.  * get_width_height
  105.  *
  106.  * tries to get values for WIDTH and HEIGHT attributes
  107.  * from file
  108.  *
  109.  * result: TRUE, if filetype has been recognised
  110.  */
  111. BOOL get_attr_size(HSCPRC * hp, HSCTAG * tag)
  112. {
  113. #define BUFSIZE  2048
  114. #define WIDTH_PNG  16           /* file indeces for PNG */
  115. #define HEIGHT_PNG 20
  116.  
  117.     HSCVAR *asrc = tag->uri_size;
  118.     STRPTR srcuri = NULL;
  119.  
  120.     if (asrc)
  121.         srcuri = get_vartext(asrc);
  122.     else
  123.     {
  124.         panic("no uri_size");
  125.     }
  126.  
  127.     if (hp->getsize && srcuri && (uri_kind(srcuri) != URI_ext))
  128.     {
  129.         STRARR buf[BUFSIZE];
  130.         EXPSTR *srcpath = init_estr(64);
  131.         EXPSTR *imgpath = init_estr(64);
  132.         ULONG width = 0;
  133.         ULONG height = 0;
  134.         BOOL transparent = FALSE;
  135.         BOOL progressive = FALSE;
  136.         STRPTR filetype = NULL;
  137.         FILE *fref = NULL;      /* file link references to */
  138.         STRARR id_PNG[8] =
  139.         {
  140.             137, 80, 78, 71, 13, 10, 26, 10
  141.         };                      /* PNG image header */
  142.  
  143.         conv_hscuri2file(hp, srcpath, srcuri);
  144.  
  145.         DSZ(fprintf(stderr, DHL "   uri : \"%s\"\n" DHL "   path: \"%s\"\n",
  146.                     srcuri, estr2str(srcpath)));
  147.  
  148.         fref = fopen(estr2str(srcpath), "r");
  149.  
  150.         if (fref)
  151.         {
  152.             /* fill buffer with zero */
  153.             memset(buf, 0, BUFSIZE);
  154.  
  155.             /* read buffer  from file */
  156.             fread(buf, BUFSIZE, 1, fref);
  157.  
  158.             if (buf[0] == 0xff)
  159.             {
  160.                 /*
  161.                  * JFIF/JPEG
  162.                  */
  163.                 BOOL found = FALSE;
  164.                 size_t i = 0;
  165.  
  166.                 /*TODO: progressive */
  167.                 while (!found && (i < BUFSIZE + 8))
  168.                 {
  169.                     if (buf[i] == 0xff)
  170.                     {
  171.                         BOOL is_msof = FALSE;
  172.                         int j = 0;
  173.  
  174.                         DSZ(fprintf(stderr,
  175.                                     "%04lx: %02x %02x: (%02x%02x %02x%02x) ",
  176.                                     (ULONG) i, buf[i], buf[i + 1],
  177.                                     buf[i + 2], buf[i + 3],
  178.                                     buf[i + 4], buf[i + 5]));
  179.  
  180.                         /* check if marker is of required type */
  181.                         while (!is_msof && msof[j])
  182.                             if (buf[i + 1] == msof[j])
  183.                                 is_msof = TRUE;
  184.                             else
  185.                                 j++;
  186.  
  187.                         if (is_msof)
  188.                         {
  189.                             DSZ(
  190.                                    {
  191.                                    for (j = 0; j < 10; j++)
  192.                                    {
  193.  
  194.                                    printf("\n  %-2d: $%02x %-3d",
  195.                                           j, buf[i + j], buf[i + j]);
  196.                                    if (buf[i + j] >= 32)
  197.                                    printf(" '%c'", buf[i + j]);
  198.  
  199.                                    }
  200.                                    }
  201.                             );
  202.  
  203.                             filetype = "JFIF/JPEG";
  204.                             width = buf[i + 8] + (buf[i + 7] << 8);
  205.                             height = buf[i + 6] + (buf[i + 5] << 8);
  206.                             found = TRUE;
  207.  
  208.                         }
  209.                         else
  210.                         {
  211.                             DDA(printf("ignore\n"));
  212.                         }
  213.                     }
  214.  
  215.                     i++;
  216.                 }
  217.  
  218.                 /* check if buffer exeeds */
  219.                 if (i >= (BUFSIZE + 8))
  220.                 {
  221.                     panic("image buffer exeeds");
  222.                 }
  223.             }
  224.             else if (!strncmp("GIF87a", buf, 6)
  225.                      || !strncmp("GIF89a", buf, 6))
  226.             {
  227.                 /*
  228.                  * GIF
  229.                  */
  230.                 LONG use_global_colormap = (buf[10] & 0x80) >> 7;
  231.                 LONG pixeldepth = (buf[10] & 0x07) + 1;
  232.                 LONG startimg =
  233.                 13 + use_global_colormap * 3 * (1 << pixeldepth);
  234.                 BOOL fucked_up = FALSE;
  235.  
  236.                 DSZ(fprintf(stderr, DHL "  buf=%d: gcolmap=%ld, pxldep=%ld\n",
  237.                             buf[10], use_global_colormap, pixeldepth));
  238.  
  239.                 while (!fucked_up && (buf[startimg] != ','))
  240.                 {
  241.                     DSZ(fprintf(stderr, DHL "  %04lx: id=%02x\n",
  242.                                 startimg, buf[startimg]));
  243.  
  244.                     if (buf[startimg] == '!')
  245.                     {
  246.                         UBYTE blksize = 0;
  247.  
  248.                         if (buf[startimg + 1] == 0xF9)
  249.                         {
  250.                             /* graphic control extensions */
  251.                             /* check if transparent */
  252.                             transparent = (buf[startimg + 3] & 0x01);
  253.                             if (transparent)
  254.                             {
  255.                                 DDA(fprintf(stderr, DHL "  (transparent)\n"));
  256.                             }
  257.                         }
  258.  
  259.                         /* skip all blocks */
  260.                         startimg += 2;
  261.                         do
  262.                         {
  263.                             blksize = buf[startimg];
  264.                             DDA(printf("  skip block sized %d\n", blksize));
  265.                             startimg += 1L + blksize;
  266.                         }
  267.                         while (!fucked_up && (blksize));
  268.  
  269.                         /* check if buffer exeeds */
  270.                         if (startimg > (BUFSIZE + 9))
  271.                         {
  272.                             panic("image buffer exeeds");
  273.                             fucked_up = TRUE;
  274.                         }
  275.  
  276.                     }
  277.                     else
  278.                     {
  279.                         panic("unknown gif-block");
  280.                         DSZ(fprintf(stderr, "  id='%x', index=%ld/\n",
  281.                                     buf[startimg], startimg));
  282.                         fucked_up = TRUE;
  283.                     }
  284.                 }
  285.  
  286.                 if ((buf[startimg] != ',') && !fucked_up)
  287.                 {
  288.                     panic("didn't find image separator");
  289.                 }
  290.                 else
  291.                 {
  292.                     /* been sucessful */
  293.                     DSZ(fprintf(stderr, DHL "  %04lx: id=%02x\n",
  294.                                 startimg, buf[startimg]));
  295.  
  296.                     filetype = "GIF";
  297.                     width = buf[startimg + 5] + 256 * buf[startimg + 6];
  298.                     height = buf[startimg + 7] + 256 * buf[startimg + 8];
  299.                     progressive = (0 != (buf[startimg + 9] & (1 << 6)));
  300.                     DDA(fprintf(stderr,
  301.                                 DHL "  width : %lu\n"
  302.                                 DHL "  height: %lu\n",
  303.                                 width, height));
  304.                 }
  305.             }
  306.             else if (!strncmp(id_PNG, buf, 8))
  307.             {
  308.                 /*
  309.                  * PNG
  310.                  */
  311.                 filetype = "PNG";
  312.                 width = 0x00800000 * buf[WIDTH_PNG] +
  313.                     0x00010000 * buf[WIDTH_PNG + 1] +
  314.                     0x00000100 * buf[WIDTH_PNG + 2] +
  315.                     0x00000001 * buf[WIDTH_PNG + 3];
  316.                 height = 0x00800000 * buf[HEIGHT_PNG] +
  317.                     0x00010000 * buf[HEIGHT_PNG + 1] +
  318.                     0x00000100 * buf[HEIGHT_PNG + 2] +
  319.                     0x00000001 * buf[HEIGHT_PNG + 3];
  320.  
  321.                 progressive = buf[HEIGHT_PNG + 9];
  322.                 /*TODO: transparent */
  323.  
  324. #if DEBUG_SIZE
  325.                 if (hp->debug)
  326.                 {
  327.                     int i;
  328.                     for (i = 0; i < BUFSIZE; i++)
  329.                     {
  330.  
  331.                         fprintf(stderr, "%-2d: $%02x %-3d", i, buf[i], buf[i]);
  332.                         if (buf[i] >= 32)
  333.                             fprintf(stderr, " '%c'\n", buf[i]);
  334.                         else
  335.                             fprintf(stderr, "\n");
  336.  
  337.                     }
  338.                 }
  339. #endif
  340.                 DDA(fprintf(stderr, DHL "  width : %lu\nheight: %lu\n",
  341.                             width, height));
  342.             }
  343.             else
  344.             {
  345.                 /* unknown file type */
  346.                 hsc_message(hp, MSG_UNKN_FILETYPE,
  347.                             "filetype of %q not recognised",
  348.                             estr2str(srcpath));
  349.             }
  350.  
  351.             DSZ(fprintf(stderr, DHL "  size: \"%s\" (%ldx%ld)\n",
  352.                         filetype, width, height));
  353.  
  354.             fclose(fref);
  355.         }
  356.         else
  357.         {
  358.             DSZ(fprintf(stderr, DHL "  Can't open image `%s'\n",
  359.                         estr2str(srcpath)));
  360.             hsc_msg_nouri(hp, estr2str(srcpath), srcuri, "image-size");
  361.         }
  362.  
  363.         /* set values */
  364.         if (height && width)
  365.         {
  366.             HSCVAR *awidth = find_varname(tag->attr, "WIDTH");
  367.             HSCVAR *aheight = find_varname(tag->attr, "HEIGHT");
  368.  
  369.             /* status message */
  370.             app_estr(srcpath, ": ");
  371.             app_estr(srcpath, filetype);
  372.             app_estr(srcpath, ", ");
  373.             app_estr(srcpath, long2str(width));
  374.             app_estr(srcpath, "x");
  375.             app_estr(srcpath, long2str(height));
  376.             if (progressive)
  377.                 app_estr(srcpath, ", progressive");
  378.             if (transparent)
  379.                 app_estr(srcpath, ", transparent");
  380.             hsc_status_misc(hp, estr2str(srcpath));
  381.  
  382.             try_setattr(hp, awidth, width);
  383.             try_setattr(hp, aheight, height);
  384.         }
  385.  
  386.         /* free local resources */
  387.         del_estr(srcpath);
  388.         del_estr(imgpath);
  389.     }
  390.  
  391.     return (TRUE);
  392. }
  393.  
  394.